package com.ruoyi.system.service.impl;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.ip.IpUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.system.domain.AppUser;
import com.ruoyi.system.service.IAppUserService;

/**
 * APP认证服务实现类
 * 
 * @author ruoyi
 */
@Service
public class AppAuthServiceImpl
{
    private static final Logger log = LoggerFactory.getLogger(AppAuthServiceImpl.class);

    @Autowired
    private IAppUserService appUserService;

    @Autowired
    private SmsServiceImpl smsService;

    @Autowired
    private RedisCache redisCache;

    @Value("${app.token.header}")
    private String header;

    @Value("${app.token.secret}")
    private String secret;

    @Value("${app.token.expireTime}")
    private int expireTime;

    /** APP Token前缀 */
    private static final String APP_TOKEN_KEY = "app_token:";

    /**
     * APP用户注册
     * 
     * @param phone 手机号
     * @param smsCode 短信验证码
     * @param password 密码
     * @param nickname 昵称
     * @return 登录结果
     */
    public Map<String, Object> register(String phone, String smsCode, String password, String nickname)
    {
        // 验证短信验证码
        if (!smsService.verifySmsCode(phone, smsCode, "1"))
        {
            throw new ServiceException("验证码验证失败");
        }

        // 检查用户是否已存在
        AppUser existUser = appUserService.selectAppUserByPhone(phone);
        if (existUser != null)
        {
            throw new ServiceException("该手机号已注册");
        }

        // 创建新用户
        AppUser newUser = new AppUser();
        newUser.setPhone(phone);
        newUser.setPassword(StringUtils.isNotEmpty(password) ? SecurityUtils.encryptPassword(password) : null);
        newUser.setNickname(StringUtils.isNotEmpty(nickname) ? nickname : "用户" + phone.substring(7));
        newUser.setStatus("0");
        newUser.setRegisterType("2"); // 完整注册
        newUser.setLoginCount(0L); // 初始化登录次数
        newUser.setRegisterTime(DateUtils.getNowDate());
        newUser.setCreateTime(DateUtils.getNowDate());

        appUserService.insertAppUser(newUser);

        log.info("APP用户注册成功，手机号：{}", phone);

        // 自动登录
        return doLogin(newUser, true);
    }

    /**
     * APP用户登录
     * 
     * @param phone 手机号
     * @param password 密码（密码登录时使用）
     * @param smsCode 短信验证码（短信登录时使用）
     * @param loginType 登录类型（1密码登录 2短信登录）
     * @param nickname 昵称（短信登录自动注册时使用）
     * @return 登录结果
     */
    public Map<String, Object> login(String phone, String password, String smsCode, String loginType, String nickname)
    {
        AppUser user = null;

        if ("1".equals(loginType))
        {
            // 密码登录
            user = passwordLogin(phone, password);
        }
        else if ("2".equals(loginType))
        {
            // 短信验证码登录
            user = smsLogin(phone, smsCode, nickname);
        }
        else
        {
            throw new ServiceException("不支持的登录类型");
        }

        return doLogin(user, false);
    }

    /**
     * 找回密码
     * 
     * @param phone 手机号
     * @param smsCode 短信验证码
     * @param newPassword 新密码
     */
    public void forgotPassword(String phone, String smsCode, String newPassword)
    {
        // 验证短信验证码
        if (!smsService.verifySmsCode(phone, smsCode, "3"))
        {
            throw new ServiceException("验证码验证失败");
        }

        // 查找用户
        AppUser user = appUserService.selectAppUserByPhone(phone);
        if (user == null)
        {
            throw new ServiceException("用户不存在");
        }

        // 更新密码
        user.setPassword(SecurityUtils.encryptPassword(newPassword));
        user.setUpdateTime(DateUtils.getNowDate());
        appUserService.updateAppUser(user);

        log.info("APP用户重置密码成功，手机号：{}", phone);
    }

    /**
     * 密码登录
     */
    private AppUser passwordLogin(String phone, String password)
    {
        AppUser user = appUserService.selectAppUserByPhone(phone);
        if (user == null)
        {
            throw new ServiceException("用户不存在");
        }

        if (StringUtils.isEmpty(user.getPassword()))
        {
            throw new ServiceException("该账号未设置密码，请使用短信验证码登录");
        }

        if (!SecurityUtils.matchesPassword(password, user.getPassword()))
        {
            throw new ServiceException("密码错误");
        }

        return user;
    }

    /**
     * 短信验证码登录（支持自动注册）
     */
    private AppUser smsLogin(String phone, String smsCode, String nickname)
    {
        // 验证短信验证码
        if (!smsService.verifySmsCode(phone, smsCode, "2"))
        {
            throw new ServiceException("验证码验证失败");
        }

        // 查找用户
        AppUser user = appUserService.selectAppUserByPhone(phone);
        
        if (user == null)
        {
            // 用户不存在，自动创建
            user = new AppUser();
            user.setPhone(phone);
            user.setNickname(StringUtils.isNotEmpty(nickname) ? nickname : "用户" + phone.substring(7));
            user.setStatus("0");
            user.setRegisterType("1"); // 短信自动注册
            user.setLoginCount(0L); // 初始化登录次数
            user.setRegisterTime(DateUtils.getNowDate());
            user.setCreateTime(DateUtils.getNowDate());

            appUserService.insertAppUser(user);
            log.info("短信登录自动创建用户，手机号：{}", phone);
        }

        return user;
    }

    /**
     * 执行登录
     */
    private Map<String, Object> doLogin(AppUser user, boolean isNewUser)
    {
        // 检查用户状态
        if (!"0".equals(user.getStatus()))
        {
            throw new ServiceException("账号已被禁用");
        }

        // 更新登录信息
        Long currentLoginCount = user.getLoginCount();
        user.setLoginCount(currentLoginCount == null ? 1L : currentLoginCount + 1L);
        user.setLastLoginTime(DateUtils.getNowDate());
        user.setLastLoginIp(IpUtils.getIpAddr());
        user.setUpdateTime(DateUtils.getNowDate());
        appUserService.updateAppUser(user);

        // 生成Token
        String token = IdUtils.fastUUID();
        String tokenKey = APP_TOKEN_KEY + token;

        // 构造用户信息
        Map<String, Object> userInfo = new HashMap<>();
        userInfo.put("userId", user.getUserId());
        userInfo.put("phone", user.getPhone());
        userInfo.put("nickname", user.getNickname());
        userInfo.put("avatar", user.getAvatar());
        userInfo.put("gender", user.getGender());

        // 存储到Redis
        redisCache.setCacheObject(tokenKey, userInfo, expireTime, TimeUnit.MINUTES);

        // 返回结果
        Map<String, Object> result = new HashMap<>();
        result.put("token", token);
        result.put("userInfo", userInfo);
        result.put("isNewUser", isNewUser);

        log.info("APP用户登录成功，手机号：{}，Token：{}", user.getPhone(), token);
        return result;
    }

    /**
     * 退出登录
     * 
     * @param token Token
     */
    public void logout(String token)
    {
        if (StringUtils.isNotEmpty(token))
        {
            String tokenKey = APP_TOKEN_KEY + token;
            redisCache.deleteObject(tokenKey);
            log.info("APP用户退出登录，Token：{}", token);
        }
    }

    /**
     * 获取用户信息
     *
     * @param token Token
     * @return 用户信息
     */
    public Map<String, Object> getUserInfo(String token)
    {
        if (StringUtils.isEmpty(token))
        {
            return null;
        }

        String tokenKey = APP_TOKEN_KEY + token;
        return redisCache.getCacheObject(tokenKey);
    }
}
